<?php

/**
 * 夏日葵电商系统
 * http://www.xiarikui.com
 */
//namespace plugins\Payment\alipay;

use Think\Model\RelationModel;

/**
 * 支付 逻辑定义
 * Class tenpay
 * @package Home\Payment
 */
class tenpay extends RelationModel {

    public $tableName = 'plugin'; // 插件表        
    public $alipay_config = array(); // 支付宝支付配置参数

    /**
     * 析构流函数
     */

    public function __construct() {
        parent::__construct();

        $paymentPlugin = M('Plugin')->where("code='tenpay' and  type = 'Payment' ")->find(); // 找到支付插件的配置
        $config_value = unserialize($paymentPlugin['config_value']); // 配置反序列化                
        $this->alipay_config['partner'] = $config_value['partner']; // 
        $this->alipay_config['key'] = $config_value['key']; //         
    }

    /**
     * 生成支付代码
     * @param   array   $order      订单信息
     * @param   array   $config_value    支付方式信息
     */
    function get_code($order, $config_value) {
        require_once ("classes/RequestHandler.class.php");
        //4位随机数
        $randNum = rand(1000, 9999);

        /* 创建支付请求对象 */
        $reqHandler = new RequestHandler();
        $reqHandler->init();
        $reqHandler->setKey($this->alipay_config['key']);
        $reqHandler->setGateUrl("https://gw.tenpay.com/gateway/pay.htm");

        //----------------------------------------
        //设置支付参数 
        //----------------------------------------
        $reqHandler->setParameter("partner", $this->alipay_config['partner']);
        $reqHandler->setParameter("out_trade_no", $order['order_sn']); //商户订单号
        $reqHandler->setParameter("total_fee", ($order['order_amount'] * 100));  //总金额
        $reqHandler->setParameter("notify_url", SITE_URL . U('Payment/notifyUrl', array('pay_code' => 'tenpay'))); //服务器异步通知页面路径 //必填，不能修改
        $reqHandler->setParameter("return_url", SITE_URL . U('Payment/returnUrl', array('pay_code' => 'tenpay'))); //页面跳转同步通知页面路径            
        $reqHandler->setParameter("body", "XiaRiKui 商城");
        $reqHandler->setParameter("bank_type", "DEFAULT");     //银行类型，默认为财付通
        //用户ip
        $reqHandler->setParameter("spbill_create_ip", $_SERVER['REMOTE_ADDR']); //客户端IP
        $reqHandler->setParameter("fee_type", "1");               //币种
        $reqHandler->setParameter("subject", "XiaRiKui商品");          //商品名称，（中介交易时必填）
        //系统可选参数
        $reqHandler->setParameter("sign_type", "MD5");       //签名方式，默认为MD5，可选RSA
        $reqHandler->setParameter("service_version", "1.0");    //接口版本号
        $reqHandler->setParameter("input_charset", "utf-8");      //字符集
        $reqHandler->setParameter("sign_key_index", "1");       //密钥序号
        //业务可选参数
        /*
          $reqHandler->setParameter("attach", "");             	  //附件数据，原样返回就可以了
          $reqHandler->setParameter("product_fee", "");        	  //商品费用
          $reqHandler->setParameter("transport_fee", "0");      	  //物流费用
          $reqHandler->setParameter("time_start", date("YmdHis"));  //订单生成时间
          $reqHandler->setParameter("time_expire", "");             //订单失效时间
          $reqHandler->setParameter("buyer_id", "");                //买方财付通帐号
          $reqHandler->setParameter("goods_tag", "");               //商品标记
          $reqHandler->setParameter("trade_mode","1");              //交易模式（1.即时到帐模式，2.中介担保模式，3.后台选择（卖家进入支付中心列表选择））
          $reqHandler->setParameter("transport_desc","");              //物流说明
          $reqHandler->setParameter("trans_type","1");              //交易类型
          $reqHandler->setParameter("agentid","");                  //平台ID
          $reqHandler->setParameter("agent_type","");               //代理模式（0.无代理，1.表示卡易售模式，2.表示网店模式）
          $reqHandler->setParameter("seller_id","");                //卖家的商户号
         */

        //请求的URL
        $reqUrl = $reqHandler->getRequestURL();

        //获取debug信息,建议把请求和debug信息写入日志，方便定位问题
        /**/
        $debugInfo = $reqHandler->getDebugInfo();
        //echo "<br/>" . $reqUrl . "<br/>";
        //echo "<br/>" . $debugInfo . "<br/>";

        $html_text = "<form style='display:none' id='tenpaysubmit' name='tenpaysubmit' action='" . $reqHandler->getGateUrl() . "' method='post'>";

        $params = $reqHandler->getAllParameters();
        foreach ($params as $k => $v) {
            $html_text .= "<input type=\"hidden\" name=\"{$k}\" value=\"{$v}\" />\n";
        }
        $html_text .= "<input type='submit' value='财付通支付'>"; //submit按钮控件请不要含有name属性
        $html_text .= "</form>";
        $html_text .= "<script>document.forms['tenpaysubmit'].submit();</script>";
        return $html_text;
    }

    /**
     * 服务器点对点响应操作给支付接口方调用
     * 
     */
    function response() {
        require ("classes/ResponseHandler.class.php");
        require ("classes/RequestHandler.class.php");
        require ("classes/client/ClientResponseHandler.class.php");
        require ("classes/client/TenpayHttpClient.class.php");
        require ("classes/function.php");

        /* 创建支付应答对象 */
        $resHandler = new ResponseHandler();
        $resHandler->setKey($this->alipay_config['key']);
        //判断签名
        if ($resHandler->isTenpaySign()) {
            //通知id
            $notify_id = $resHandler->getParameter("notify_id");
            //通过通知ID查询，确保通知来至财付通
            //创建查询请求
            $queryReq = new RequestHandler();
            $queryReq->init();
            $queryReq->setKey($this->alipay_config['key']);
            $queryReq->setGateUrl("https://gw.tenpay.com/gateway/simpleverifynotifyid.xml");
            $queryReq->setParameter("partner", $this->alipay_config['partner']);
            $queryReq->setParameter("notify_id", $notify_id);
            //通信对象
            $httpClient = new TenpayHttpClient();
            $httpClient->setTimeOut(5);
            //设置请求内容
            $httpClient->setReqContent($queryReq->getRequestURL());

            //后台调用
            if ($httpClient->call()) {
                //设置结果参数
                $queryRes = new ClientResponseHandler();
                $queryRes->setContent($httpClient->getResContent());
                $queryRes->setKey($this->alipay_config['key']);
                if ($resHandler->getParameter("trade_mode") == "1") {
                    //判断签名及结果（即时到帐）
                    //只有签名正确,retcode为0，trade_state为0才是支付成功
                    if ($queryRes->isTenpaySign() && $queryRes->getParameter("retcode") == "0" && $resHandler->getParameter("trade_state") == "0") {
                        log_result("即时到帐验签ID成功");
                        //取结果参数做业务处理
                        $out_trade_no = $resHandler->getParameter("out_trade_no");
                        //财付通订单号
                        $transaction_id = $resHandler->getParameter("transaction_id");
                        //金额,以分为单位
                        $total_fee = $resHandler->getParameter("total_fee");
                        //如果有使用折扣券，discount有值，total_fee+discount=原请求的total_fee
                        $discount = $resHandler->getParameter("discount");

                        //------------------------------
                        //处理业务开始
                        //------------------------------
                        //处理数据库逻辑
                        //注意交易单不要重复处理
                        //注意判断返回金额
                        update_pay_status($out_trade_no); // 修改订单支付状态
                        //------------------------------
                        //处理业务完毕
                        //------------------------------
                        log_result("即时到帐后台回调成功");
                        echo "success";
                    } else {
                        //错误时，返回结果可能没有签名，写日志trade_state、retcode、retmsg看失败详情。
                        //echo "验证签名失败 或 业务错误信息:trade_state=" . $resHandler->getParameter("trade_state") . ",retcode=" . $queryRes->                         getParameter("retcode"). ",retmsg=" . $queryRes->getParameter("retmsg") . "<br/>" ;
                        log_result("即时到帐后台回调失败");
                        echo "fail";
                    }
                } elseif ($resHandler->getParameter("trade_mode") == "2") {
                    //判断签名及结果（中介担保）
                    //只有签名正确,retcode为0，trade_state为0才是支付成功
                    if ($queryRes->isTenpaySign() && $queryRes->getParameter("retcode") == "0") {
                        log_result("中介担保验签ID成功");
                        //取结果参数做业务处理
                        $out_trade_no = $resHandler->getParameter("out_trade_no");
                        //财付通订单号
                        $transaction_id = $resHandler->getParameter("transaction_id");
                        //金额,以分为单位
                        $total_fee = $resHandler->getParameter("total_fee");
                        //如果有使用折扣券，discount有值，total_fee+discount=原请求的total_fee
                        $discount = $resHandler->getParameter("discount");

                        //------------------------------
                        //处理业务开始
                        //------------------------------
                        //处理数据库逻辑
                        //注意交易单不要重复处理
                        //注意判断返回金额                        

                        log_result("中介担保后台回调，trade_state=" + $resHandler->getParameter("trade_state"));
                        switch ($resHandler->getParameter("trade_state")) {
                            case "0": //付款成功
                                break;
                            case "1": //交易创建
                                break;
                            case "2": //收获地址填写完毕
                                break;
                            case "4": //卖家发货成功
                                break;
                            case "5": //买家收货确认，交易成功
                                break;
                            case "6": //交易关闭，未完成超时关闭
                                break;
                            case "7": //修改交易价格成功
                                break;
                            case "8": //买家发起退款
                                break;
                            case "9": //退款成功
                                break;
                            case "10": //退款关闭			
                                break;
                            default:
                                //nothing to do
                                break;
                        }
                        //------------------------------
                        //处理业务完毕
                        //------------------------------
                        update_pay_status($out_trade_no); // 修改订单支付状态
                        echo "success";
                    } else {
                        //错误时，返回结果可能没有签名，写日志trade_state、retcode、retmsg看失败详情。
                        //echo "验证签名失败 或 业务错误信息:trade_state=" . $resHandler->getParameter("trade_state") . ",retcode=" . $queryRes->             										       getParameter("retcode"). ",retmsg=" . $queryRes->getParameter("retmsg") . "<br/>" ;
                        log_result("中介担保后台回调失败");
                        echo "fail";
                    }
                }
                //获取查询的debug信息,建议把请求、应答内容、debug信息，通信返回码写入日志，方便定位问题
                /*
                  echo "<br>------------------------------------------------------<br>";
                  echo "http res:" . $httpClient->getResponseCode() . "," . $httpClient->getErrInfo() . "<br>";
                  echo "query req:" . htmlentities($queryReq->getRequestURL(), ENT_NOQUOTES, "GB2312") . "<br><br>";
                  echo "query res:" . htmlentities($queryRes->getContent(), ENT_NOQUOTES, "GB2312") . "<br><br>";
                  echo "query reqdebug:" . $queryReq->getDebugInfo() . "<br><br>" ;
                  echo "query resdebug:" . $queryRes->getDebugInfo() . "<br><br>";
                 */
            } else {
                //通信失败
                echo "fail";
                //后台调用通信失败,写日志，方便定位问题
                echo "<br>call err:" . $httpClient->getResponseCode() . "," . $httpClient->getErrInfo() . "<br>";
            }
        } else {
            echo "<br/>" . "认证签名失败" . "<br/>";
            echo $resHandler->getDebugInfo() . "<br>";
        }
    }

    /**
     * 页面跳转响应操作给支付接口方调用
     */
    function respond2() {
        require_once ("classes/ResponseHandler.class.php");
        require_once ("classes/function.php");
        //require_once ("tenpay_config.php");
        log_result("进入前台回调页面");

        /* 创建支付应答对象 */
        $resHandler = new ResponseHandler();
        $resHandler->setKey($this->alipay_config['key']);
        //判断签名
        if ($resHandler->isTenpaySign()) {
            //通知id
            $notify_id = $resHandler->getParameter("notify_id");
            //商户订单号
            $out_trade_no = $resHandler->getParameter("out_trade_no");
            //财付通订单号
            $transaction_id = $resHandler->getParameter("transaction_id");
            //金额,以分为单位
            $total_fee = $resHandler->getParameter("total_fee");
            //如果有使用折扣券，discount有值，total_fee+discount=原请求的total_fee
            $discount = $resHandler->getParameter("discount");
            //支付结果
            $trade_state = $resHandler->getParameter("trade_state");
            //交易模式,1即时到账
            $trade_mode = $resHandler->getParameter("trade_mode");
            if ("1" == $trade_mode) {
                if ("0" == $trade_state) {
                    //------------------------------
                    //处理业务开始
                    //------------------------------
                    //注意交易单不要重复处理
                    //注意判断返回金额
                    //------------------------------
                    //处理业务完毕
                    //------------------------------	

                    return array('status' => 1, 'order_sn' => $out_trade_no); //跳转至成功页面
                    //echo "<br/>" . "即时到帐支付成功" . "<br/>";
                } else {
                    //当做不成功处理
                    return array('status' => 0, 'order_sn' => $out_trade_no); //跳转至失败页面    
                    //echo "<br/>" . "即时到帐支付失败" . "<br/>";
                }
            } elseif ("2" == $trade_mode) {
                if ("0" == $trade_state) {

                    //------------------------------
                    //处理业务开始
                    //------------------------------
                    //注意交易单不要重复处理
                    //注意判断返回金额
                    //------------------------------
                    //处理业务完毕
                    //------------------------------	
                    return array('status' => 1, 'order_sn' => $out_trade_no); //跳转至成功页面
                    //echo "<br/>" . "中介担保支付成功" . "<br/>";
                } else {
                    //当做不成功处理
                    return array('status' => 0, 'order_sn' => $out_trade_no); //跳转至失败页面    
                    //echo "<br/>" . "中介担保支付失败" . "<br/>";
                }
            }
        } else {
            return array('status' => 0, 'order_sn' => $out_trade_no); //跳转至失败页面
            //echo "<br/>" . "认证签名失败" . "<br/>";
            //echo $resHandler->getDebugInfo() . "<br>";
        }
    }

}
